﻿#include "description.h"
#include <QDebug>
#include <QFile>

Description::Description() : m_isAllInitialized(false) {

}

QList<Device *> Description::pDevices() const
{
    return m_pDevices;
}

QList<Step *> Description::pSteps() const
{
    return m_pSteps;
}

void Description::clear(){
    m_pDevices.clear();
    m_pSteps.clear();
}

bool Description::writeXML(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        qWarning() << "Unable to open file:" << filePath;
        return false;
    }

    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);

    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("Description");
    //////////////////////////////////////////////////////////////
    /// 开始写入内容 devices
    xmlWriter.writeStartElement("Devices");
    foreach (Device *pDevice, m_pDevices) {
        pDevice->writeXML(xmlWriter);
    }
    xmlWriter.writeEndElement();
    //////////////////////////////////////////////////////////////
    /// 开始写入内容 steps
    xmlWriter.writeStartElement("Steps");
    foreach (Step *pStep, m_pSteps) {
        pStep->writeXML(xmlWriter);
    }
    xmlWriter.writeEndElement();
    /////////////////////////////////////////////////////////////
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();

    file.close();
    return true;
}

bool Description::ReadXML(const QString &filePath)
{
    QList<QString> toolsList;
    QFile file(filePath);

    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "Unable to open file:" << filePath;
        return false;
    }

    QXmlStreamReader xmlReader(&file);

    // 读取 XML 直到结束
    while (!xmlReader.atEnd() && !xmlReader.hasError()) {
        xmlReader.readNext();

        // 如果是 Description 元素的开始
        if (xmlReader.isStartElement() && xmlReader.name() == QStringLiteral("Description")) {
            // 读取 description 元素内部
            while (!(xmlReader.tokenType() == QXmlStreamReader::EndElement
                     && xmlReader.name() == QStringLiteral("Description"))) {
                xmlReader.readNext();

                if (xmlReader.isStartElement() && xmlReader.name() == QStringLiteral("Devices")) {
                    while (!(xmlReader.tokenType() == QXmlStreamReader::EndElement
                             && xmlReader.name() == QStringLiteral("Devices"))) {
                        xmlReader.readNext();
                        if (xmlReader.isStartElement()) {
                            QString className = xmlReader.name().toString();
                            Device *pDevice = (Device *) ObjectFactory::createObject(
                                className.toLatin1(),this);
                            if (pDevice != NULL) {
                                pDevice->readFromXML(xmlReader);
                                //pDevice->initDevice();
                                this->AddDevice(pDevice);
                            }
                        }
                    }
                }

                if (xmlReader.isStartElement() && xmlReader.name() == QStringLiteral("Steps")) {
                    while (!(xmlReader.tokenType() == QXmlStreamReader::EndElement
                             && xmlReader.name() == QStringLiteral("Steps"))) {
                        xmlReader.readNext();
                        if (xmlReader.isStartElement()) {
                            QString className = xmlReader.name().toString();
                            Step *pStep = (Step *) ObjectFactory::createObject(className.toLatin1(),
                                                                               this);
                            if (pStep != NULL) {
                                pStep->readFromXML(xmlReader);
                                this->AddStep(pStep);
                            }
                        }
                    }
                }
            }
        }
    }

    // 检查 XML 是否有解析错误
    if (xmlReader.hasError()) {
        qWarning() << "XML error:" << xmlReader.errorString();
    }

    file.close();
    return true;
}

Device *Description::FindDeviceById(QString strID)
{
    foreach (Device *pDevice, m_pDevices) {
        if (pDevice->getStrID() == strID) {
            return pDevice;
        }
    }

    return NULL;
}

void Description::run()
{
    initAllDevices();

    foreach (Step *pStep, m_pSteps) {
        qDebug() << "Step is Running!";
        pStep->run();
    }
    qDebug() << "Run is finished!";
}

void Description::test()
{
    initAllDevices();
    uninitAllDevices();
    qDebug() << "Test is finished!";
}

void Description::initAllDevices(){
    if(!m_isAllInitialized){
        foreach (Device *pDevice, m_pDevices) {
            qDebug() << pDevice->initDevice();
        }
        m_isAllInitialized = true;
    }
}

void Description::uninitAllDevices(){
    if(m_isAllInitialized){
        foreach (Device *pDevice, m_pDevices) {
            pDevice->uninitDevice();
        }
        m_isAllInitialized = false;
    }
}

void Description::ReceviceCmdFromVirtualDevice(QVariant variant){
    emit SendCmdToMainWindow(variant);
}
